/*
 AddPower.cpp

 Created on: Jan 12, 2009
     Author: sez
 */

#include "AddPower.h"
#include "ui_addpower.h"

#include <Models/DataListModel.h>
#include <Xml/XmlException.h>
#include <DndData/Power.h>

#include <QMessageBox>
#include <QStringListModel>
#include <QInputDialog>

/*!
\class AddPower
\brief Dialog to capture new Power items, and edit existing ones.
\details A QDialog sub-class, this class manages all aspects of the
 capturing and editing, writing any changed data out to the XML data file
 on the file-system.  The return value of the dialog can be used to see if
 a model should be refreshed due to a changed data item.

 A LoadSave dialog should be used to capture a
 title for the proposed or edited power.
*/

struct AddPowerModels
{
    SimpleRaceModel *mRaceModel;
    SimpleClassModel *mClassModel;
};

/*!
\brief Construct a new AddPower
\details The
*/
AddPower::AddPower(QWidget *parent)
    : AddUpdateDialog(XmlPath(XmlPath::CLASS_BASE), parent)
    , mAddPower(new Ui::AddPowerDialog())
    , mModels(new AddPowerModels())
    , mData(0)
{
    mAddPower->setupUi(this);
    XmlPath xp(xmlPath());
    xp.setSubType(XmlPath::POWER_TYPE);
    setXmlPath(xp);
}

AddPower::~AddPower()
{
    delete mAddPower;
    delete mModels;
    delete mData;
}

/*!
  \brief Return the instance of the AddPower dialog.
  This method is first called during the construction of the QMainWindow,
  and at this time the instance is initialized with the main window as its
  \a parent.  With this invariant, the method is thread-safe, otherwise it
  is not.  On subsequent calls the already initialized instance is returned
  and any argument is ignored.
 */
AddPower *AddPower::dialog(QWidget *parent)
{
    static AddPower *dlg = 0;
    if (dlg == 0)
        dlg = new AddPower(parent);
    return dlg;
}

void AddPower::setupData()
{
    mModels->mRaceModel = makeSimpleRaceModel(this);
    mModels->mClassModel = makeSimpleClassModel(this);
    for (int i = 0; i < Power::NUM_POWER_AVAILABILITY; ++i)
            mAddPower->availabilityComboBox->addItem(Power::POWER_AVAILABILITY_NAMES[i]);
    mKeywordModel = new QStringListModel(this);
    mAddPower->deleteKeywordToolButton->setEnabled(false);
}

TitledData *AddPower::data()
{
    if (!mData)
        mData = new Power(xmlPath());
    return mData;
}

void AddPower::saveData()
{
    mData->level = mAddPower->levelSpinBox->value();
    mData->type = mAddPower->attackRadioButton->isChecked() ? Power::ATTACK_POWER : Power::UTILITY_POWER;
    int index = mAddPower->availabilityComboBox->currentIndex();
    mData->availability = static_cast<Power::PowerAvailability>(index);
    mData->text = mAddPower->descriptionTextEdit->document()->toPlainText();
    mData->type = mAddPower->attackRadioButton->isChecked() ?
                  Power::ATTACK_POWER : Power::UTILITY_POWER;
    int a = mAddPower->availabilityComboBox->currentIndex();
    Q_ASSERT(a < Power::NUM_POWER_AVAILABILITY && a > -1);
    mData->availability = static_cast<Power::PowerAvailability>(a);
    mData->keywords = mKeywordModel->stringList();
    a = mAddPower->actionCostComboBox->currentIndex();
    Q_ASSERT(a < Power::NUM_ACTION_COSTS && a > -1);
    mData->actionCost = static_cast<Power::ActionCost>(a);
    a = mAddPower->rangeTypeComboBox->currentIndex();
    Q_ASSERT(a < Power::NUM_RANGE_TYPES && a > -1);
    mData->range = static_cast<Power::RangeType>(a);
    //mData->target =
}

void AddPower::loadData()
{
    mAddPower->powerSummaryLabel->setText(QString("%1 %2 Power").arg(xmlPath().typeName())
                                         .arg(XmlPath::BASE_TYPE_NAMES[xmlPath().type()]));
    mAddPower->levelSpinBox->setValue(mData->level);
    mAddPower->attackRadioButton->setChecked(mData->type == Power::ATTACK_POWER);
    mAddPower->utilityRadioButton->setChecked(mData->type == Power::UTILITY_POWER);
    mAddPower->availabilityComboBox->setCurrentIndex(mData->availability);
    mAddPower->descriptionTextEdit->document()->setPlainText(mData->text);
    mKeywordModel->setStringList(mData->keywords);
    mAddPower->actionCostComboBox->setCurrentIndex(mData->actionCost);
    mAddPower->rangeTypeComboBox->setCurrentIndex(mData->range);
}

void AddPower::clearData()
{
    mAddPower->levelSpinBox->setValue(0);
    mAddPower->attackRadioButton->setChecked(true);
    mAddPower->utilityRadioButton->setChecked(false);
    mAddPower->availabilityComboBox->setCurrentIndex(0);
    mAddPower->descriptionTextEdit->document()->setPlainText("");
    mKeywordModel->setStringList(QStringList());
    mAddPower->actionCostComboBox->setCurrentIndex(0);
    mAddPower->rangeTypeComboBox->setCurrentIndex(0);
}

void AddPower::on_deleteKeywordToolButton_clicked(bool)
{
    QModelIndexList selected = mAddPower->keywordsListView->selectionModel()->selectedIndexes();
    Q_ASSERT(selected.size() < 2);
    if (selected.size() == 0)
    {
        QMessageBox::critical(this, tr("No selection"),
                        tr("Select a keyword to delete"));
        return;
    }
    int count = mKeywordModel->rowCount();
    int row = selected.first().row();
    mKeywordModel->removeRows(row, 1);
    if (count == 1)
        mAddPower->deleteKeywordToolButton->setEnabled(false);
}

void AddPower::on_addKeywordToolButton_clicked(bool)
{
    bool ok;
    QString text = QInputDialog::getText(this, tr("Enter a new keyword"),
                                         tr("Keyword:"), QLineEdit::Normal,
                                         "keyword", &ok);
    if (ok && !text.isEmpty() && text == "keyword")
    {
        int row = mKeywordModel->rowCount();
        mKeywordModel->insertRows(row, 1); // append one row
        mKeywordModel->setData(mKeywordModel->index(row), text);
        mAddPower->deleteKeywordToolButton->setEnabled(true);
    }
}
